﻿Imports System.Drawing
Imports System.Windows.Forms
Imports Microsoft.HomeServer.Extensibility
Imports Microsoft.HomeServer.SDK.Interop.v1

''' <summary>
''' The main class of the add-in, represents the settings tab you see in the whs console.
''' </summary>
''' <remarks></remarks>
Public Class HomeServerSettingsExtender
    Implements ISettingsTab

    ''' <summary>
    ''' The control that houses the controls for the configuration of the add-in
    ''' </summary>
    ''' <remarks></remarks>
    Private m_TabControl As TwoFactorSettings

    ''' <summary>
    ''' The console services provided by the host environment.
    ''' </summary>
    ''' <remarks></remarks>
    Private m_Services As IConsoleServices

    ''' <summary>
    ''' The application folder in which to persist settings.
    ''' </summary>
    ''' <remarks></remarks>
    Private m_AppFolder As IApplicationFolder

    ''' <summary>
    ''' For identifying the application folder for storing settings.
    ''' </summary>
    ''' <remarks></remarks>
    Private m_AppSettingsGuid As Guid = New Guid("A6B681C3-9939-438d-88C2-D4E2881C1F82")

    ''' <summary>
    ''' The path to the file in which to persist and load settings from
    ''' </summary>
    ''' <remarks></remarks>
    Private m_SettingsFileName As String

    ''' <summary>
    ''' The loaded settings for the add-in.
    ''' </summary>
    ''' <remarks></remarks>
    Private m_Settings As YubiVerifier.Settings

    Public Sub New(ByVal pWidth As Integer, ByVal pHeight As Integer, ByVal pConsoleServices As IConsoleServices)
        Try
            Dim _whsinfo As New WHSInfoClass
            'Create an application folder for the add-in
            Try
                m_AppFolder = _whsinfo.GetApplicationFolder(m_AppSettingsGuid)
            Catch ex As Exception
                m_AppFolder = _whsinfo.CreateApplicationFolder(m_AppSettingsGuid, "TwoFactorWHS")
            End Try

            'Create the host for our settings controls.
            m_TabControl = New TwoFactorSettings(pWidth, pHeight)
            m_SettingsFileName = IO.Path.Combine(m_AppFolder.Path, "settings.xml")
            m_Settings = New YubiVerifier.Settings(m_SettingsFileName)
            m_TabControl.Settings = m_Settings

            PopulateFormFromSettings()
        Catch ex As Exception
            'for now, dump errors into a text box on the form.
            m_TabControl.txtError.Text = ex.ToString
        End Try
        'console services arent actually needed currently, but hold onto them anyway.
        m_Services = pConsoleServices
    End Sub

    ''' <summary>
    ''' not at the moment. you are on your own.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetHelp() As Boolean Implements Microsoft.HomeServer.Extensibility.IConsoleTab.GetHelp
        Return False
    End Function

    ''' <summary>
    ''' links the settings pane of the add-in to the console tab, if we were providing one.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property SettingsGuid() As System.Guid Implements Microsoft.HomeServer.Extensibility.IConsoleTab.SettingsGuid
        Get
            Return New Guid("{8CD7AC69-1D65-41ef-BCBF-59AD4EE37B23}")
        End Get
    End Property

    ''' <summary>
    ''' The host for the controls for the settings tab.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property TabControl() As System.Windows.Forms.Control Implements Microsoft.HomeServer.Extensibility.IConsoleTab.TabControl
        Get
            Return m_TabControl
        End Get
    End Property

    ''' <summary>
    ''' our image resource for the icon
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property TabImage() As System.Drawing.Bitmap Implements Microsoft.HomeServer.Extensibility.IConsoleTab.TabImage
        Get
            Return My.Resources.Two_Factor
        End Get
    End Property

    ''' <summary>
    ''' The title of the add-in
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property TabText() As String Implements Microsoft.HomeServer.Extensibility.IConsoleTab.TabText
        Get
            Return "TwoFactor WHS"
        End Get
    End Property

    ''' <summary>
    ''' Populate our form from the settings object that we have loaded.
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub PopulateFormFromSettings()
        m_TabControl.txtAppID.Text = m_Settings.AppID
        m_TabControl.txtURL.Text = m_Settings.Url
        m_TabControl.txtAppKey.Text = m_Settings.AppKey
        m_TabControl.chkRedirect.Checked = m_Settings.IsDeployed
        m_TabControl.numReload.Value = m_Settings.ReloadInterval
        m_TabControl.chkLogFailures.Checked = m_Settings.EnableAuthenticationLogging

        Dim _sb As New System.Text.StringBuilder

        'TODO: clean up the way these settings are persisted and loaded.
        For Each _key As String In m_Settings.Users.Keys
            _sb.AppendLine(_key.ToLower & "|" & m_Settings.Users.Item(_key))
        Next
        m_TabControl.txtUsers.Text = _sb.ToString
        m_TabControl.RefreshErrors()
    End Sub

    ''' <summary>
    ''' Transfer the settings from the form to our persistable object.
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub GatherSettingsFromForm()
        m_Settings.Url = m_TabControl.txtURL.Text
        m_Settings.AppID = m_TabControl.txtAppID.Text
        m_Settings.AppKey = m_TabControl.txtAppKey.Text
        m_Settings.ReloadInterval = CInt(m_TabControl.numReload.Value)
        m_Settings.EnableAuthenticationLogging = m_TabControl.chkLogFailures.Checked

        Dim _sr As New IO.StringReader(m_TabControl.txtUsers.Text)
        Dim _line As String = _sr.ReadLine()
        m_Settings.Users.Clear()
        While _line IsNot Nothing
            Dim _user() As String = _line.Split("|"c)
            If _user.Length <> 2 Then
                Throw New Exception("Username and public id must be seperated by | character.")
            End If
            m_Settings.Users.Add(_user(0).ToLower, _user(1).ToLower)
            _line = _sr.ReadLine
        End While
        _sr.Close()
    End Sub

    ''' <summary>
    ''' Perform the redirection operation, modifying the remote access login page.
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub PerformRedirect()
        Try
            'grab our settings and save them
            GatherSettingsFromForm()
            m_Settings.Save()

            'create the loginredirector to modify the login page.
            Dim _l As New LoginRedirector(m_Settings.Url, m_Settings.AppKey, m_Settings.AppID, m_SettingsFileName)
            _l.RedirectLogon()

            'remember that we are deployed.
            m_Settings.IsDeployed = True
            m_Settings.Save()
        Catch ex As Exception
            'alert the user that something went wrong with the operation. 
            MsgBox(ex.ToString)
            m_TabControl.chkRedirect.Checked = False
            Try
                m_Settings.LogError(ex.ToString)
                m_TabControl.RefreshErrors()
            Catch _ex As Exception
                'Suppress errors
            End Try
        End Try
    End Sub

    ''' <summary>
    ''' Reverts the modified login page to default.
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub PerformUnRedirect()
        Try
            'grab our settings and save them
            GatherSettingsFromForm()
            m_Settings.Save()

            'create the loginredirector to revert the login page to standard.
            Dim _l As New LoginRedirector(m_Settings.Url, m_Settings.AppKey, m_Settings.AppID, m_SettingsFileName)
            _l.UnRedirectLogon()

            'remember that our modification has been retracted.
            m_Settings.IsDeployed = False
            m_Settings.Save()
        Catch ex As Exception
            'alert the user that something went wrong with the operation.
            MsgBox(ex.ToString)
            m_TabControl.chkRedirect.Checked = True
            Try
                m_Settings.LogError(ex.ToString)
                m_TabControl.RefreshErrors()
            Catch _ex As Exception
                'Suppress errors
            End Try
        End Try
    End Sub

    ''' <summary>
    ''' the apply button or the ok button has been clicked.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Commit() As Boolean Implements Microsoft.HomeServer.Extensibility.ISettingsTab.Commit
        'If the value of the redirect checkbox has changed from what was persisted last, then we need
        'to act on the change.
        If m_TabControl.chkRedirect.Checked <> m_Settings.IsDeployed Then
            If m_TabControl.chkRedirect.Checked Then
                PerformRedirect()
            Else
                PerformUnRedirect()
            End If
            Return True
        Else
            'Still save settings
            GatherSettingsFromForm()
            m_Settings.Save()
            Return True
        End If
    End Function
End Class
